package org.chronologger.poppaea.client.widgets;

import org.chronologger.poppaea.client.utils.HasColor;

import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;

public class SegmentedButton extends Composite implements HasColor {

	private final FlowPanel parts = new FlowPanel();
	private String color = "red";
	private String hoverColor = "#ff9600";
	private final MouseOverHandler mouseOver = new MouseOverHandler() {
		public void onMouseOver(MouseOverEvent event) {
			if (!hoverColor.equals(""))
				event.getRelativeElement().getStyle().setProperty(
						"backgroundColor", hoverColor);
		}
	};
	private final MouseOutHandler mouseOut = new MouseOutHandler() {
		public void onMouseOut(MouseOutEvent event) {
			event.getRelativeElement().getStyle().setProperty(
					"backgroundColor", color);
			event.getRelativeElement().getStyle().setProperty(
					"backgroundImage", "");
		}
	};
	private final MouseDownHandler mouseDown = new MouseDownHandler() {

		public void onMouseDown(MouseDownEvent event) {
			event.getRelativeElement().getStyle().setProperty(
					"backgroundImage", "url(graphics/location-bg-inv.png)");
			event.preventDefault();
		}
	};
	private final MouseUpHandler mouseUp = new MouseUpHandler() {

		public void onMouseUp(MouseUpEvent event) {
			event.getRelativeElement().getStyle().setProperty(
					"backgroundImage", "");
			event.preventDefault();
		}
	};

	public SegmentedButton() {
		initWidget(parts);
		parts.setStyleName("segmented-button");
	}

	public Anchor addSegment(String text) {
		return addSegment(text, false);
	}

	public Anchor addSegment(String text, boolean asHTML) {
		Anchor anchor = new Anchor(text, asHTML);
		anchor.getElement().getStyle().setProperty("backgroundColor", color);
		anchor.addMouseOverHandler(mouseOver);
		anchor.addMouseOutHandler(mouseOut);
		anchor.addMouseDownHandler(mouseDown);
		anchor.addMouseUpHandler(mouseUp);
		parts.add(anchor);

		switch (parts.getWidgetCount()) {
		case 1:
			anchor.setStyleName("segmented-button-only");
			break;
		case 2:
			parts.getWidget(0).setStyleName("segmented-button-first");
			anchor.setStyleName("segmented-button-last");
			break;
		default:
			parts.getWidget(parts.getWidgetCount() - 2).setStyleName(
					"segmented-button-middle");
			anchor.setStyleName("segmented-button-last");
			break;
		}

		return anchor;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		if (!this.color.equals(color)) {
			this.color = color;
			for (int i = parts.getWidgetCount() - 1; i >= 0; i--) {
				getSegment(i).getElement().getStyle().setProperty(
						"backgroundColor", color);
			}
		}
	}

	public void setHoverColor(String hoverColor) {
		this.hoverColor = hoverColor;
	}

	public Anchor getSegment(int index) {
		return (Anchor) parts.getWidget(index);
	}

	/**
	 * Sets a segment's real size (including padding, excluding border)
	 * 
	 * @param width
	 * @param height
	 */
	public void setSegmentSize(int segment, int width, int height) {
		getSegment(segment).setPixelSize(width - 6, height);
	}

	/**
	 * Resets this button's segments' hover state. (Workaround for MouseOut
	 * event not always firing)
	 */
	public void resetHoverState() {
		String color = getColor();
		this.color = "";
		setColor(color);
	}
}